package com.xnyzc.lhy.order.controller.auth;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.component.sms.AliCloudSMSUtils;
import com.xnyzc.lhy.common.constant.AliCloudSmsConstant;
import com.xnyzc.lhy.common.constant.CommonConstant;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.entity.netty.NettyDriverOrderInfo;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.ELoginUserType;
import com.xnyzc.lhy.common.util.*;
import com.xnyzc.lhy.order.common.constants.SmsCodeTypeConstant;
import com.xnyzc.lhy.order.entity.common.order.OrderCommon;
import com.xnyzc.lhy.order.entity.order.OaCOrder;
import com.xnyzc.lhy.order.entity.param.auth.DetectionToken;
import com.xnyzc.lhy.order.entity.param.auth.LoginToken;
import com.xnyzc.lhy.order.entity.param.auth.SmsCode;
import com.xnyzc.lhy.order.entity.system.OaSysGlobalConfig;
import com.xnyzc.lhy.order.service.auth.IOaAuthService;
import com.xnyzc.lhy.order.service.order.IOaOrderCommonService;
import com.xnyzc.lhy.order.service.sms.IOaSmsCodeRecordService;
import com.xnyzc.lhy.order.service.sms.IOaSmsErrorCodeService;
import com.xnyzc.lhy.order.service.system.IOaSysGlobalConfigService;
import com.xnyzc.lhy.order.service.user.IOaDUserService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户登录相关
 * </p>
 *
 * @author lhy@xnyzc.com
 * @since 2019-07-22
 */
@Slf4j
@RestController
@RequestMapping("/oa/auth")
public class OaAuthController {


    @Autowired
    IOaOrderCommonService iOaOrderCommonService;


    @Autowired
    IOaAuthService iOaAuthService;

    @Autowired
    IOaSmsCodeRecordService iOaSmsCodeRecordService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    IOaSysGlobalConfigService iOaSysGlobalConfigService;

    @Autowired
    IOaSmsErrorCodeService iOaSmsErrorCodeService;

    @Autowired
    IOaDUserService iOaDUserService;

    @Autowired
    RedisCommon redisCommon;

    @Autowired
    OrderCommon orderCommon;


    @PostMapping("/addRedisOrder")
    public Rv addRedisOrder() {
        String orderNo = "GRGW201909258576303357";
        OaCOrder order = orderCommon.selectOn(orderNo);
        NettyDriverOrderInfo orderInfo = BeanUtil.copyProperties(order, NettyDriverOrderInfo.class);
        redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + orderNo, JSON.toJSONString(orderInfo));
        return Rv.wrap("666");
    }

    /**
     * 获取短信手机验证码
     *
     * @return
     */
    @ApiOperation(value = "获取手机短信验证码", notes = "获取手机短信验证码")
    @PostMapping("/getSmsCode")
    public Rv getSmsCode(@ApiParam(name = "smsCode", value = "短信信息") @RequestBody SmsCode smsCode) {

        String phone = smsCode.getPhone();
        Integer codeType = smsCode.getCodeType();
        // 用户类型
        String userType = TokenUtil.getUserType();
        String tag = TokenUtil.getTag();

        if (CheckUtil.objIsEmpty(phone, codeType, userType, tag)) {
            throw PangException.create(EErrorCode.missingArg);
        }

        // 如果为绑定银行卡请求，那么验证是否与此司机手机号一致
        if (SmsCodeTypeConstant.BIND_BANK_CARD_TYPE.equals(codeType)) {
            Long driverId = TokenUtil.getTokenUserId();
            String driverPhone = iOaDUserService.getDriverPhone(driverId);
            if (!phone.equals(driverPhone)) {
                throw PangException.create(EErrorCode.bankCardPhoneFaild);
            }
        }

        // 获取全局配置信息
        OaSysGlobalConfig oaSysGlobalConfig = iOaSysGlobalConfigService.getTagOne(tag);
        if (CheckUtil.objIsEmpty(oaSysGlobalConfig)) {
            throw PangException.create(EErrorCode.noData);
        }

        // 检查是否已超出错误次数
        Boolean checkErrorCount = iOaSmsErrorCodeService.getCheckErrorCount(oaSysGlobalConfig, phone, ConvertUtil.toInt(userType), tag);
        if (!checkErrorCount) {
            throw PangException.create(EErrorCode.exceedLimit);
        }
        Integer smsLimitExpireTime = CommonConstant.REDIS_REDIS_SMS_LIMIT_EXPIRE_TIME;
        if (!CheckUtil.objIsEmpty(oaSysGlobalConfig.getCodeValidTime())) {
            smsLimitExpireTime = oaSysGlobalConfig.getCodeValidTime();
        }
        // 验证码key
        String smsCodeKey = CommonConstant.REDIS_SMS_LIMIT + "_" + tag + "_" + userType + "_" + phone;
        if (redisTemplate.hasKey(smsCodeKey)) {
            // 删除key
            redisTemplate.delete(smsCodeKey);
            //  throw PangException.create(EErrorCode.apiRstError, "验证码每" + smsLimitExpireTime + "秒可获取一次");
        }

        // 获取4位数验证码
        String code = RandomUtil.getRandomNumberStr(4);
        redisTemplate.opsForValue().set(smsCodeKey, code, ConvertUtil.toLong(smsLimitExpireTime), TimeUnit.SECONDS);
        // 发送验证码
        JSONObject smsJson = new JSONObject();
        smsJson.put("code", code);
        try {
            //QCloudSMSUtils.sendMessage(phone, QCloudSmsConstant.VERIFICATION_CODE, smsJson);
            AliCloudSMSUtils.sendMessage(phone, AliCloudSmsConstant.VERIFICATION_CODE, smsJson);
        } catch (Exception e) {
        }

        // 保存验证码
        iOaSmsCodeRecordService.saveCode(phone, code, codeType, userType, tag);

        return Rv.wrap(Qd.create().add("code", 0000));
    }

    /**
     * 根据手机登陆
     *
     * @return
     */
    @ApiOperation(value = "用户登陆", notes = "用户登录")
    @PostMapping("/loginToken")
    @ResponseBody
    public Rv loginToken(@ApiParam(name = "smsCode", value = "短信信息") @RequestBody LoginToken loginToken) {
        if (CheckUtil.objIsEmpty(loginToken, loginToken.getSourceId(), loginToken.getCredentials(), loginToken.getLoginUserType())) {
            throw PangException.create(EErrorCode.missingArg);
        }

        String token = "";
        // 乘客端登录
        if (Objects.equals(loginToken.getLoginUserType(), ELoginUserType.c.toString())) {
            log.info("乘客端登录");
            token = iOaAuthService.getLoginTokenByC(loginToken);
        }
        // 司机端登录
        else if (Objects.equals(loginToken.getLoginUserType(), ELoginUserType.d.toString())) {
            log.info("司机端登录");
            Map<String, String> map = iOaAuthService.getLoginTokenByD(loginToken);
            map.put("token", CommonConstant.TOKEN_SPLIT + map.get("token"));
            return Rv.wrap(map);
        }
        // 管理员
        else if (Objects.equals(loginToken.getLoginUserType(), ELoginUserType.fm.toString())) {
            log.info("管理员登录");
            token = iOaAuthService.getLoginTokenBySys(loginToken);
        }
        // 平台管理员
        else if (Objects.equals(loginToken.getLoginUserType(), ELoginUserType.manager.toString())) {
            log.info("平台管理登录");
        }
        //后端app管理员登录
        else if(Objects.equals(loginToken.getLoginUserType(), "app")){
            log.info("后端app管理员登录获取用户信息");
            return Rv.wrap(iOaAuthService.getLoginTokenBySys2(loginToken));
        }
        if (CheckUtil.objIsEmpty(token)) {
            throw PangException.create(EErrorCode.noData);
        }
        return Rv.wrap(Qd.create().add("token", CommonConstant.TOKEN_SPLIT + token));
    }

    /**
     * 判断token是否真实
     *
     * @return
     */
    @ApiOperation(value = "判断token是否真实", notes = "判断token是否真实")
    @PostMapping("/detectionToken")
    @ResponseBody
    public Rv detectionToken(@ApiParam(name = "smsCode", value = "登录信息") @RequestBody DetectionToken detectionToken) {
        if (CheckUtil.objIsEmpty(detectionToken.getToken())) {
            throw PangException.create(EErrorCode.noData);
        }
        return Rv.wrap(iOaAuthService.getDetectionToken(detectionToken));
    }

    /**
     * 获取乘客端用户信息
     *
     * @return
     */
    @ApiOperation(value = "获取乘客端用户信息", notes = "获取乘客端用户信息")
    @GetMapping(value = "/getUserInfo")
    // @ResponseBody
    public Rv getUserInfo(@RequestParam(value = "userId") Long userId) {
        return Rv.wrap(iOaOrderCommonService.getUserInfo(userId));
    }

    /**
     * 修改乘客端用户手机号
     *
     * @return
     */
    @ApiOperation(value = "修改乘客绑定的手机号", notes = "修改乘客绑定的手机号")
    @PostMapping("/modifyUserPhone")
    @ResponseBody
    public Rv modifyUserPhone(@RequestBody HashMap<String, String> map) {

        String smsCode = map.get("smsCode");
        String oldTel = map.get("oldTel");
        String newTel = map.get("newTel");
        String tag = map.get("tag");
        //验参是否为空
        if (CheckUtil.objIsEmpty(smsCode, oldTel, newTel)) {
            throw PangException.create(EErrorCode.noData);
        }
        return Rv.wrap(iOaAuthService.modifyUserPhone(smsCode, oldTel, newTel, tag));
    }


    /**
     * 修改乘客端用户信息
     *
     * @return
     */
    @ApiOperation(value = "修改用户信息", notes = "修改用户信息")
    @PostMapping(value = "/modifyUserInfo")
    @ResponseBody
    public Rv modifyUserInfo(@RequestBody HashMap<String, String> map) {
        //验参是否为空
        if (CheckUtil.objIsEmpty(map)) {
            throw PangException.create(EErrorCode.noData);
        }
        return Rv.wrap(iOaAuthService.modifyUserInfo(map));
    }


    /**
     * 用户认证接口
     *
     * @return
     */
    @ApiOperation(value = "用户认证接口", notes = "用户认证接口")
    @PostMapping(value = "/userRealAuth")
    @ResponseBody
    public Rv userRealAuth(@RequestBody HashMap<String, String> map) {
        //验参是否为空
        if (CheckUtil.objIsEmpty(map)) {
            throw PangException.create(EErrorCode.noData);
        }
        return Rv.wrap(iOaAuthService.userRealAuth(map));
    }

    /**
     * 添加司机用户反馈信息
     *
     * @param map
     * @return
     * @author jon
     */
    @ApiOperation(value = "添加司机用户反馈", notes = "添加司机用户反馈")
    @PostMapping("/addFeedBack")
    @ResponseBody
    public Rv addFeedBack(@RequestBody HashMap<String, String> map) {

        //验参是否为空
        if (CheckUtil.objIsEmpty(map)) {
            throw PangException.create(EErrorCode.missingArg);
        }
        return Rv.wrap(iOaAuthService.addFeedBack(map));
    }
}
